package com.fengmi.service;

import cn.hutool.json.JSONUtil;
import com.api.cms.CmsApi;
import com.api.goods.GoodsApi;
import com.fengmi.cms.entity.Content;
import com.fengmi.consts.RedisKey;
import com.fengmi.goods.vo.GoodsCatVo;
import com.fengmi.goods.vo.HotGoodsVo;
import org.redisson.api.RBloomFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class CacheService implements ICacheService{


   @Autowired
   private CmsApi cmsApi;


   @Autowired
   private GoodsApi goodsApi;


   @Autowired
   private StringRedisTemplate stringRedisTemplate;

    /**
     * string list hash set zset
     * 内容列表   轮播图 :[]  公告:[]  通知:[]
     *  list
     *  1:[]
     *  2:[]
     *  3:[]
     *
     *  hash(不推荐)
     *  cms:
     *    1:[]=>json
     *    2:[]=>json
     *    3:[]=>json
     *  string
     *  1:[]=>json
     *  2:[]=>json
     *  3:[]=>json
     *
     *
     *
     * @param catId
     * @return
     */

    @Autowired
    private RBloomFilter<Object>  bloomFilter;


    @Override
    public List<Content> cacheContent(String catId/*-1*/) {
          //基于redis参数校验
//          if(!stringRedisTemplate.boundSetOps("catId").isMember(catId)){//时间复杂度O(n)
//              return new ArrayList<>();
//          }

           //基于布隆过滤器参数校验
           if(!bloomFilter.contains(catId)){ //时间复杂度O(k)
               return new ArrayList<>();
           }


            BoundValueOperations<String, String> opt = stringRedisTemplate.boundValueOps(RedisKey.VALID_CONTENT_TYPE_ID + ":"+catId);
            String cmsListJson = opt.get();

            if(!StringUtils.isEmpty(cmsListJson)){

                //从redis中获取
                System.out.println("get from  redis.....");
                return JSONUtil.toList(cmsListJson,Content.class);

            }else{
                synchronized (this) {

                    String cmsListJsonAgain = opt.get();
                    if(StringUtils.isEmpty(cmsListJsonAgain)){
                        System.out.println("get from  db .......");
                        //从数据库中获取
                        List<Content> contentListByCatId = cmsApi.findContentListByCatId(catId);
                        if(!CollectionUtils.isEmpty(contentListByCatId)){
                            //缓存到redis中
                            opt.set(JSONUtil.toJsonStr(contentListByCatId));
                            //设置过期时间
                            opt.expire(1, TimeUnit.DAYS);
                        }
                        return contentListByCatId;
                    }else{
                        System.out.println("get from redis ...");
                        return JSONUtil.toList(cmsListJsonAgain,Content.class);
                    }

                }
            }


    }



    @Override
    public List<GoodsCatVo> cacheGoodsCat() {
        return goodsApi.cascade();
    }


    @Override
    public List<HotGoodsVo> cacheHotGoods() {

        return  goodsApi.findHotGoods();
    }
}
